#ifndef _B5M_COMMON_PROCESS_MUTEX_H_
#define _B5M_COMMON_PROCESS_MUTEX_H_

#include "common.h"
#include "B5M_Mutex.h"

B5M_BEGIN_VERSIONED_NAMESPACE_DECL

class B5M_Export B5M_Process_Mutex
{
public:
  /**
   * Create an B5M_Process_Mutex.
   *
   * @param name optional, null-terminated string containing the name of
   * the object. Multiple users of the same @c B5M_Process_Mutex must use
   * the same name to access the same object.  If not specified, a name
   * is generated.
   */
  B5M_Process_Mutex (wchar_t *name = 0);
  /**
   * Destructor.
   *
   * @note The destructor will not release an acquired mutex except
   * on Windows.
   */
  ~B5M_Process_Mutex (void);

  /**
   * Explicitly destroy the mutex.  Note that only one thread should
   * call this method since it doesn't protect against race
   * conditions.
   *
   * @return 0 on success; -1 on failure.
   */
  int remove (void);

  /**
   * Acquire lock ownership (wait on queue if necessary).
   *
   * @return 0 on success; -1 on failure.
   */
  int acquire (void);

  /**
   * Acquire lock ownership, but timeout if lock if hasn't been
   * acquired by given time.
   *
   * @param timeout the absolute time until which the caller is willing to
   * wait to acquire the lock.
   *
   * @return 0 on success; -1 on failure.
   */
  int acquire (B5M_UINT32 timeout);

  /**
   * Conditionally acquire lock (i.e., don't wait on queue).
   *
   * @return 0 on success; -1 on failure.  If the lock could not be acquired
   * because someone else already had the lock, @c errno is set to @c EBUSY.
   */
  int tryacquire (void);

  /// Release lock and unblock a thread at head of queue.
  int release (void);

private:
  /// If the user does not provide a name we generate a unique name in
  /// this buffer.
  wchar_t name_[B5M_UNIQUE_NAME_LEN];

  /// Create and return the unique name.
  const wchar_t *unique_name (void);

  //lock object
  B5M_Mutex lock_;

  //nonecopy
  B5M_NONE_COPYABLE(B5M_Process_Mutex);
};

B5M_END_VERSIONED_NAMESPACE_DECL

#endif